'''
////////////////////////////////////////////////////////////////////
//                            _ooOoo_                             //
//                           o8888888o                            //
//                           88" . "88                            //
//                           (| ^_^ |)                            //
//                           O\  =  /O                            //
//                        ____/`---'\____                         //
//                      .'  \\|     |//  `.                       //
//                     /  \\|||  :  |||//  \                      //
//                    /  _||||| -:- |||||-  \                     //
//                    |   | \\\  -  /// |   |                     //
//                    | \_|  ''\---/''  |   |                     //
//                    \  .-\__  `-`  ___/-. /                     //
//                  ___`. .'  /--.--\  `. . ___                   //
//                ."" '<  `.___\_<|>_/___.'  >'"".                //
//              | | :  `- \`.;`\ _ /`;.`/ - ` : | |               //
//              \  \ `-.   \_ __\ /__ _/   .-` /  /               //
//        ========`-.____`-.___\_____/___.-`____.-'========       //
//                             `=---='                            //
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      //
//        佛祖保佑             永无BUG              永不修改         //
////////////////////////////////////////////////////////////////////
'''


import sys
import cv2 as cv
import torch
from PyQt5.QtWidgets import QMainWindow, QApplication, QTextEdit
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import QTimer, QThread, pyqtSignal

from main_window1 import Ui_MainWindow

import time
import serial
import struct
import glob

# 使用glob.glob查找以/dev/ttyUSB开头的所有串口
# 这将返回一个列表，其中包含匹配的串口名称
# available_ports = glob.glob('/dev/ttyUSB*')

# if not available_ports:
#     print("没有找到可用的串口。")
# else:
#     # 选择第一个匹配的串口（你可以根据需要修改选择逻辑）
#     selected_port = available_ports[0]
#     print(selected_port)

# serial_port = serial.Serial(
#     port=selected_port,
#     baudrate=38400,
#     bytesize=serial.EIGHTBITS,
#     parity=serial.PARITY_NONE,
#     stopbits=serial.STOPBITS_ONE,
#     timeout=1
# )

'''
ub=struct.pack('BBBB BBBB BBBB BBBB BB',
                |0x66,|  0x55 ,| 0x3A,|0xB4,0x00,0x00,| 0x00,| 0x00,0x00,0x00,| 0x00,| 0x00,0x00,0x00| 0x00,| 0x00,0x00,0x00)
                |0X66 |垃圾种类 |y轴正负| y值 拆分成三位  |x轴正负|  x值,拆分成三位   |y轴正负|  y值 拆分成三位 |x轴正负| x值,拆分成三位 
                |     |        | 0x01+|               | 0x01+|                | 0x01+|               | 0x01+|
                |     |        | 0x02-|               | 0x02-|                | 0x02-|               | 0x02-|
'''
A = 0x00

Recycle = struct.pack('BBBB BBBB', 0x77, 0x01, A, A, A, A, A, A)

Harmful = struct.pack('BBBB BBBB', 0x77, 0x02, A, A, A, A, A, A)

Kitchen = struct.pack('BBBB BBBB', 0x77, 0x03, A, A, A, A, A, A)

Others = struct.pack('BBBB BBBB', 0x77, 0x04, A, A, A, A, A, A)

MaxDet = struct.pack('BBBB BBBB', 0x88, A, A, A, A, A, A, A)

def convert2QImage(img):
    height, width, channel = img.shape
    return QImage(img, width, height, width * channel, QImage.Format_RGB888)


def sent_command(com):
    serial_port.write(com)

def read_mess():
    # 读取一个字节的串口数据
    data = serial_port.read(1)

    # 将接收的数据转换为十六进制
    received_value = int.from_bytes(data, byteorder='big', signed=False)

    return received_value

R = 0
H = 0
K = 0
O = 0

class VideoThread(QThread):
    frame_processed = pyqtSignal(QImage)
    text_processed = pyqtSignal(str)
    x1_y1_updated = pyqtSignal(int, int, int, int, int)  # 新的信号用于发送x1, x2, y1, y2, kind的值
    maxdet_triggered = pyqtSignal()

    def __init__(self, model):
        super().__init__()
        self.model = model
        global x1,x2,y1,y2

    def run(self):
        self.cont = 0
        global R, H, K, O
        self.det = cv.VideoCapture(0)
        self.det.set(cv.CAP_PROP_FRAME_WIDTH, 1280)
        self.det.set(cv.CAP_PROP_FRAME_HEIGHT, 720)
        self.det.set(cv.CAP_PROP_EXPOSURE, 15000)
        
        while True:
            ret, frame = self.det.read()
            if not ret:
                print("Error: Unable to read frame.")
                self.det.release()
                break
            else:
                height, width, _ = frame.shape

                # # 计算裁剪的起始坐标
                x = (width - 640) // 2
                y = (height - 560) // 2

                # 进行中心裁剪
                frame = frame[y:y + 640, x:x + 640]

                frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
                results = self.model(frame)
                image = results.render()[0]
                df = results.pandas().xyxy[0]
                self.frame_processed.emit(convert2QImage(image))

                detection_texts = []

                for i, row in df.iterrows():
                    xmin = int(row['xmin'])
                    ymin = int(row['ymin'])
                    xmax = int(row['xmax'])
                    ymax = int(row['ymax'])
                    class_id = int(row['class'])
                    labels = row['name']

                    # bbox = f"{xmin}  {ymin}  {xmax}  {ymax}"
                    # detection_text = f"{class_id}, {x_center_px, y_center_px}, {x_psc1, x_psc2, y_psc1, y_psc2}, {labels}"
                    # detection_texts.append(detection_text)

                    if labels == 'battery' or labels == 'drug' or labels == 'pill':
                        H += 1
                        self.kind = 0x02
                        if H % 60 == 0:
                            self.cont += 1
                            sent_command(Harmful)
                            H = 0
                            R = 0
                            K = 0
                            O = 0
                            text = f'{self.cont} 有害垃圾 1 OK!'
                            self.text_processed.emit(text)
                            print("Harmful sent")

                    if labels == 'bottle' or labels == 'can':
                        R += 1
                        self.kind = 0x01
                        if R % 60 == 0:
                            self.cont += 1
                            sent_command(Recycle)
                            text = f'{self.cont} 可回收垃圾 1 OK!'
                            H = 0
                            R = 0
                            K = 0
                            O = 0
                            self.text_processed.emit(text)
                            print("Recycle sent")
                            # self.Max_Com()

                    if labels == 'carrot' or labels == 'turnip':
                        K += 1
                        self.kind = 0x03
                        if K % 60 == 0:
                            self.cont += 1
                            sent_command(Kitchen)
                            H = 0
                            R = 0
                            K = 0
                            O = 0
                            text = f'{self.cont} 厨余垃圾 1 OK!'
                            self.text_processed.emit(text)
                            print("Kitchen sent")

                    if labels == 'potato' or labels == 'chip' or labels == 'brick':
                        O += 1
                        self.kind = 0x04
                        if O % 60 == 0:
                            self.cont += 1
                            sent_command(Others)
                            H = 0
                            R = 0
                            K = 0
                            O = 0
                            text = f'{self.cont} 其他垃圾 1 OK!'
                            self.text_processed.emit(text)
                            print("Others sent")


                # self.text_processed.emit("\n".join(detection_texts))    # 合并发送所有检测信息

                # time.sleep(0.01)
c=0
class SerialThread(QThread):
    serial_data_received = pyqtSignal(int)

    def __init__(self):
        super().__init__()

    def run(self):
        # global c
        while True:
            # c+=1
            # if c%13==0:
            #     sent_command(Others)
            # sent_command(MaxDet)
            received_value = read_mess()
            self.serial_data_received.emit(received_value)
            self.msleep(500)  # 休眠1秒钟，可以根据需要调整
            


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        self.ccc = 0
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.model = torch.hub.load("./", "custom", path="m_Final_v25.pt", source='local')
        self.model.conf = 0.7
        self.model.iou = 0.4
        self.output_mess = self.findChild(QTextEdit, "output_mess")
        self.maxdet_mess = self.findChild(QTextEdit, "maxdet_mess")

        self.video_thread = VideoThread(self.model)
        self.video_thread.frame_processed.connect(self.update_realtime_det)
        self.video_thread.text_processed.connect(self.show_mess)
        self.video_thread.maxdet_triggered.connect(self.show_maxdet_mess)

        self.serial_thread = SerialThread()
        self.serial_thread.serial_data_received.connect(self.handle_serial_data)
        self.serial_thread.start()

        self.video_thread.start()

        self.timer = QTimer()
        self.timer.setInterval(1)
        self.timer.timeout.connect(self.open_video)
        self.det = None

        self.text_style()
        self.video_show()

    def handle_serial_data(self, received_value):
        self.ccc+=1
        print(f"Received value: 0x{received_value:02X}, {self.ccc}")  # 打印接收到的十六进制值
        if received_value == 0x01:
            self.show_maxdet_mess()
        # elif received_value == 0x99:
        #     sent_command(MaxDet)
        #     print("MaxDet Sent")
        elif received_value == 0x10:
            self.maxdet_mess.clear()
            

    def open_video(self):
        ret, frame = self.video.read()
        if not ret:
            print("Error: Unable to read frame.")
            self.timer.stop()
        else:
            frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
            self.video_player.setPixmap(QPixmap.fromImage(convert2QImage(frame)))

    def video_show(self):
        self.video = cv.VideoCapture('./1_1.mp4')
        if not self.video.isOpened():
            print("Error: Unable to open mp4.")
            return
        else:
            self.timer.start()

    def show_mess(self, text):
        self.output_mess.setText(text)

    def text_style(self):
        styleSheet = "QTextEdit{font-size: 50px; color: rgb(100, 200, 0);}"
        maxdet_mess_styleSheet = "QTextEdit{font-size: 50px; color: rgb(255, 0, 0); text-align: center;}"
        self.output_mess.setStyleSheet(styleSheet)
        self.maxdet_mess.setStyleSheet(maxdet_mess_styleSheet)

    def update_realtime_det(self, image):
        self.realtime_det.setPixmap(QPixmap.fromImage(image))

    def show_maxdet_mess(self):
        # self.maxdet_mess.setPlainText("75%满载预警")  # 使用setPlainText设置文本
        self.maxdet_mess.setText("75%满载预警")  # 使用setPlainText设置文本

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()
